package com.eric.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eric.domain.dto.EquipmentDto;
import com.eric.domain.dto.EquipmentPhotoDto;
import com.eric.domain.po.EquipTransfer;
import com.eric.domain.po.Equipment;
import com.eric.domain.po.EquipmentPhoto;
import com.eric.mapper.EquipmentMapper;
import com.eric.service.IEquipmentPhotoService;
import com.eric.service.IEquipmentService;
import com.eric.service.ILocationService;
import com.eric.service.ISysUserService;
import com.eric.utils.FilesDownLoad;
import com.eric.utils.PublicTools;
import com.eric.utils.ServerBASEURL;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.DeleteJoinWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.github.yulichang.wrapper.UpdateJoinWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.eric.utils.Constant.PAGE_CURRENT;
import static com.eric.utils.Constant.PAGE_SIZE;

/**
 * <p>
 * 设备库存表 服务实现类
 * </p>
 *
 * @author 新哥
 * @since 2024-03-12
 */
@Service
@RequiredArgsConstructor
public class EquipmentServiceImpl extends MPJBaseServiceImpl<EquipmentMapper, Equipment> implements IEquipmentService {
    //    配置encode的前缀
    private final static String ENCODE_PREFIX = "EQUIP";
    private final EquipmentMapper equipmentMapper;

    //   判断当前用户权限的布尔值,用于通过登录用户的权限，选择性地决定是否通过location查询数据
//    private final boolean ROLE_FLAG=PublicTools.checkLoginRole();

    //    用于做创建服务器磁盘的文件夹-日期
    SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
    //    用于做图片文件的文件名
    SimpleDateFormat tdf = new SimpleDateFormat("yyyyMMdd");

    @Value("${file.location}")
    String fileLocation;
    //    用于做创建服务器磁盘的文件夹
    String equipPhotoPath = "/equipPhotos";
    //    调用equipmentPhotoService，用于存储图片
    private final IEquipmentPhotoService equipmentPhotoService;
    //    通过userService获取到真是名称用于equipment中的create_by和last_update_by
    private final ISysUserService userService;
    private final ILocationService locationService;

    @Override
    @Transactional
    public SaResult saveOneService(EquipmentDto equipmentDto, MultipartFile[] eqPhotoList, HttpServletRequest request) {
        if(BeanUtil.isEmpty(equipmentDto)){
            return SaResult.error("设备对象不能为空");
        }
//        去掉多余的空字符串
        EquipmentDto checkedEquipmentDto = checkEquipmentDto(equipmentDto);
        if (StrUtil.isBlank(checkedEquipmentDto.getEqName())){
            return SaResult.error("设备名称不能为空");
        }
        if (StrUtil.isBlank(checkedEquipmentDto.getModel())){
            return SaResult.error("设备型号不能为空");
        }
        if (StrUtil.isBlank(checkedEquipmentDto.getBrand())){
            return SaResult.error("设备品牌不能为空");
        }
        if (StrUtil.isBlank(checkedEquipmentDto.getPieces())){
            return SaResult.error("设备数量单位不能为空");
        }

//        下面四行生成Encode
        String encode_suffix = RandomUtil.randomString(5).toUpperCase();
        String dateFormat = tdf.format(new Date());
        String equip_encode = ENCODE_PREFIX + dateFormat + encode_suffix;
        checkedEquipmentDto.setEncode(equip_encode);

//        通过locationService，获取到location地址，判断用户是否有分配项目或者仓库地址
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
//        把location字符串放在equipmentDto中
        checkedEquipmentDto.setLocation(locationAddress);

//        如果MultipartFile[]不为空
        if (eqPhotoList!=null){
//        这里是调用一个方法，用于另外一个表的文件写入及数据库信息写入，传递参数有encode,eqPhotoList,request
            boolean b=fileOperation(equip_encode, eqPhotoList, request);
        }
        Equipment equipment = BeanUtil.copyProperties(checkedEquipmentDto, Equipment.class);
//
//            通过登录id和userService，获取到用户的realName
        String realname = userService.getById(Integer.parseInt(StpUtil.getLoginId().toString())).getRealName();
//            把获取到的realName设定为表中的Create_by字段
        equipment.setCreateBy(realname);
//
        equipment.setNumber(1);
        save(equipment);
        return SaResult.data(checkedEquipmentDto);
    }

    @Override
    public SaResult getAllByPageService(Integer current, Integer pageSize) {
        if (current == null||current<=0) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null||pageSize<=0) {
            pageSize = PAGE_SIZE;
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
//       应该用EquipmentDto，而不是Equipment，因为后面返回的是EquipmentDto对象
        Page<EquipmentDto> page = new Page<>(current, pageSize);
        page.setSize(pageSize);
        page.setCurrent(current);
        page.setOptimizeCountSql(false);

        MPJLambdaWrapper<Equipment>wrapper=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
//                PublicTools.checkLoginRole返回一个boolean值，根据登陆人权限，如果登陆人的权限满足一定要求，就会判定时候启动这个locationAddress校验功能
//                如果返回true，这里搜索到的数据，是只针对登陆人所在的地区搜索数据，如果是false，就可以全部搜索。
//                所以，权限足够高，那么，就是false，这个eq不工作，如果权限不够高，就是true，eq工作
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
                .eq("status",1)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)

                ;

        //      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPage = selectJoinListPage(page, EquipmentDto.class, wrapper);
        List<EquipmentDto> equipmentDtoList = equipmentDtoPage.getRecords();
        return SaResult.data(equipmentDtoList);
    }

    @Override
    public SaResult getAllCountsService() {
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        MPJLambdaWrapper<Equipment>wrapper=new MPJLambdaWrapper<Equipment>()
                .select( "count(id)")
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress);
        Long l = selectJoinOne(Long.class, wrapper);
        return SaResult.data(l);
    }

    @Override
    public SaResult getOneByIdService(Integer id) {
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        MPJLambdaWrapper<Equipment>wrapper=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
                .eq(Equipment::getId,id)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode);
        EquipmentDto equipmentDto = selectJoinOne(EquipmentDto.class, wrapper);

        List<EquipmentPhoto> equipmentPhotoList = equipmentDto.getEquipmentPhotoList();
        if (equipmentPhotoList!=null){
            for (EquipmentPhoto equipmentPhoto : equipmentPhotoList) {
                String photoUrl = equipmentPhoto.getPhotoUrl();
                String fullPhotoUrl = ServerBASEURL.BASEURL + photoUrl;
                equipmentPhoto.setPhotoUrl(fullPhotoUrl);
            }
        }


        return SaResult.data(equipmentDto);
    }

//    @Override
//    public SaResult getOneByEncodeService(String encode) {
//        if (StrUtil.isBlank(StrUtil.trim(encode))){
//            return SaResult.error("encode输入不正确");
//        }
//        String locationAddress = locationService.getAllByLoginId();
//        if (StrUtil.isBlank(locationAddress)) {
//            return SaResult.error("当前用户没有分配项目或者仓库地址");
//        }
//        MPJLambdaWrapper<Equipment>wrapper=new MPJLambdaWrapper<Equipment>()
//                .selectAll(Equipment.class)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .eq(Equipment::getEncode,encode)
//                .eq(PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode);
////        EquipmentDto equipmentDto = selectJoinOne(EquipmentDto.class, wrapper);
//        List<EquipmentDto> equipmentDtoList = selectJoinList(EquipmentDto.class, wrapper);
//        return SaResult.data(equipmentDtoList);
//    }

    @Override
    @Transactional
    public SaResult modifyOneService(EquipmentDto equipmentDto, MultipartFile[] eqPhotoList, HttpServletRequest request,String[] photoList) {

//         检查对象字段，把空字符串设定设null
        EquipmentDto checkedEquipmentDto = checkEquipmentDto(equipmentDto);
        if (checkedEquipmentDto.getId()==null||checkedEquipmentDto.getId()<=0){
            return SaResult.error("id值不符合要求");
        }
        Equipment equipmentInDb = query().eq("id", checkedEquipmentDto.getId()).one();
        if (BeanUtil.isEmpty(equipmentInDb)){
            return SaResult.error("没有此项设备，请核实");
        }

       /* if (StrUtil.isBlank(StrUtil.trim(checkedEquipmentDto.getEncode()))){
            return SaResult.error("encode不能为空");
        }

//   todo   检测传进来的encode和数据库中的encode是否一致 看看这句代码有没有问题
        Equipment equipmentEncode = query().eq("id", checkedEquipmentDto.getId()).select("encode").one();
        if (!equipmentDto.getEncode().equals(equipmentEncode.getEncode())){

            return SaResult.error("encode和数据库中的encode不匹配");
        }*/
//         这项判定不需要了
//        if (equipmentDto.getNumber()<0||equipmentDto.getNumber()>1){
//            return SaResult.error("设备数量不能为负数或者大于1");
//        }

//        删除前端传进来的文件名的文件
        if (photoList!=null&&photoList.length>0){
//            for (String photoUrl : photoList) {
////            1、截取“file/”后面的字符串
//                String substring = photoUrl.substring(photoUrl.indexOf("e") + 2);
////            2、删除文件
//                boolean del = FileUtil.del(fileLocation + substring);
//            }

//        逻辑删除equipment_photo表中对一个前端传进来的文件名的文件的数据
            equipmentPhotoService.deleteByPhotoUrlList(Arrays.asList(photoList));
        }

        EquipmentDto equipmentDtoByQuery = BeanUtil.copyProperties(equipmentInDb, EquipmentDto.class);
        if (eqPhotoList!=null){
            fileOperation(equipmentDtoByQuery.getEncode(),eqPhotoList,request);
        }
//        获取登录用户id
        Object loginId1 = StpUtil.getLoginId();
        int i = Integer.parseInt(loginId1.toString());
//            通过登录id和userService，获取到用户的realName
        String realName = userService.getById(i).getRealName();
//            把获取到的realName设定为表中的Create_by字段
        Equipment equipment = BeanUtil.copyProperties(checkedEquipmentDto, Equipment.class);
        equipment.setLastUpdateBy(realName);


//     todo   这里有个逻辑，就是equipment的数据修改完成后，对应的equipmentTransfer表单相应字段也应该修改
        EquipTransfer equipTransfer = BeanUtil.copyProperties(equipment, EquipTransfer.class);
        equipTransfer.setId(null);
        Integer equipId = equipment.getId();
        equipTransfer.setEquipId(equipId);

//      使用myabais-plus-join的联表修改方式
        UpdateJoinWrapper<Equipment>update=JoinWrappers.update(Equipment.class)
//                设定修改从表的对象
                .setUpdateEntity(equipTransfer)
//                第一个参数是主表类名，第二个是主从表的关联字段
                .leftJoin(EquipTransfer.class, EquipTransfer::getEquipId,Equipment::getId)
//                       设定从表的查询条件
                .eq(Equipment::getId,equipId);
//        调用Mapper的updateJoin方法，进行联表修改
        int updated = equipmentMapper.updateJoin(equipment, update);
        return updated>0?SaResult.ok("修改成功"):SaResult.error("修改失败");

    }


    @Override
    @Transactional
    public SaResult deleteOneById(Integer id) {
        if (id==null||id<=0){
            return SaResult.error("id参数错误");
        }
        //        联表删除
        DeleteJoinWrapper<Equipment> wrapper= JoinWrappers.delete(Equipment.class)
                .deleteAll()
                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                .eq(Equipment::getId,id);
        boolean b = deleteJoin(wrapper);
        return SaResult.ok("succeed!");
    }


    //    这个接口是对应管理员使用的
//    @Override
//    public SaResult getByLocation(Integer current, Integer pageSize, String location) {
//        if (current == null||current<=0) {
//            current = PAGE_CURRENT;
//        }
//        if (pageSize == null||pageSize<=0) {
//            pageSize = PAGE_SIZE;
//        }
//        String locationAddress = locationService.getAllByLoginId();
//        if (StrUtil.isBlank(locationAddress)) {
//            return SaResult.error("当前用户没有分配项目或者仓库地址");
//        }
//
//        //       应该用EquipmentDto，而不是Equipment，因为后面返回的是EquipmentDto对象
//        Page<EquipmentDto> page = new Page<>(current, pageSize);
////        跟一对多一样
//        MPJLambdaWrapper<Equipment>wrapper=new MPJLambdaWrapper<Equipment>()
//                .selectAll(Equipment.class)
//                .like("location",location)
//                .eq(PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
//                .orderByDesc("create_time")
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode);
////      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
////        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
//        Page<EquipmentDto> equipmentDtoPage = selectJoinListPage(page, EquipmentDto.class, wrapper);
//        List<EquipmentDto> equipmentDtoList = equipmentDtoPage.getRecords();
//        return SaResult.data(equipmentDtoList);
//    }


    @Override
    public SaResult getByTypeName(String typeName, Integer orderBy, Integer current, Integer pageSize) {
        if (StrUtil.isEmpty(typeName)) {
            return SaResult.error("类型名称不能为空");
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        if (current==null||current<=0){
            current = PAGE_CURRENT;
        }
        if (pageSize==null||pageSize<=0){
            pageSize = PAGE_SIZE;
        }
        if (orderBy==null||orderBy<=0){
            return SaResult.error("orderBy值不能为空或者小于等于零！");
        }
        boolean desc=true;
        boolean asc=false;
        if (orderBy!=1){
            desc=false;
            asc=true;
        }

        Page<EquipmentDto>page=new Page<>(current,pageSize);
        //        跟一对多一样
        MPJLambdaWrapper<Equipment>wrapper=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .eq("type_name",typeName)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPage = selectJoinListPage(page, EquipmentDto.class, wrapper);
        List<EquipmentDto> equipmentDtoList = equipmentDtoPage.getRecords();
        return SaResult.data(equipmentDtoList);
    }


    public SaResult getCountsByTypeNameService(String typeName){
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        MPJLambdaWrapper<Equipment>wrapper=new MPJLambdaWrapper<Equipment>()
                .select( "count(id)")
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
                .eq("type_name",typeName);

        Long l = selectJoinOne(Long.class, wrapper);
        return SaResult.data(l);
    }
//    @Override
//    public void downLoadFileService(String fileName, HttpServletResponse response) throws IOException {
//        FilesDownLoad.fileSend(FilesDownLoad.urlToLocalName(fileName,fileLocation),response);
//    }

    @Override
    public void downloadFilesService(String[] files, HttpServletResponse response) throws IOException {
        FilesDownLoad.filesToZip(response,files,fileLocation);
    }

    @Override
    public SaResult getByEquipmentNameService(String equipmentName,Integer current,Integer pageSize) {

        if (current == null||current<=0) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null||pageSize<=0) {
            pageSize = PAGE_SIZE;
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        if (StrUtil.isBlank(StrUtil.trim(equipmentName))){
            return SaResult.error("查询的设备名称不能为空！");
        }

        //       应该用EquipmentDto，而不是Equipment，因为后面返回的是EquipmentDto对象
        Page<EquipmentDto> page = new Page<>(current, pageSize);
//        跟一对多一样
        MPJLambdaWrapper<Equipment>wrapper=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("eq_name",equipmentName)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPage = selectJoinListPage(page, EquipmentDto.class, wrapper);
        List<EquipmentDto> equipmentDtoList = equipmentDtoPage.getRecords();
        return SaResult.data(equipmentDtoList);
    }

    @Override
    public SaResult getByMultifunctionService(String name, Integer current, Integer pageSize) {
        if (current == null||current<=0) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null||pageSize<=0) {
            pageSize = PAGE_SIZE;
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        if (StrUtil.isBlank(StrUtil.trim(name))){
            return SaResult.error("查询的名称不能为空！");
        }
//        通过设备名称查询

//       应该用EquipmentDto，而不是Equipment，因为后面返回的是EquipmentDto对象
        Page<EquipmentDto> page = new Page<>(current, pageSize);
        Set<EquipmentDto>finalResultList=new HashSet<>();
//        跟一对多一样
        MPJLambdaWrapper<Equipment>wrapperByEquipName=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("eq_name",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPageByEquipmentName = selectJoinListPage(page, EquipmentDto.class, wrapperByEquipName);
        List<EquipmentDto> equipmentDtoListByEquipmentName = equipmentDtoPageByEquipmentName.getRecords();
        if (!equipmentDtoListByEquipmentName.isEmpty()){
            finalResultList.addAll(equipmentDtoListByEquipmentName);
        }

//        根据设备类型查询
        MPJLambdaWrapper<Equipment>wrapperByTypeName=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("type_name",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPageByTypeName = selectJoinListPage(page, EquipmentDto.class, wrapperByTypeName);
        List<EquipmentDto> equipmentDtoListByTypeName = equipmentDtoPageByTypeName.getRecords();
        if (!equipmentDtoListByTypeName.isEmpty()){
            finalResultList.addAll(equipmentDtoListByTypeName);
        }

//        根据创建人名称查询
        MPJLambdaWrapper<Equipment>wrapperByCreateBy=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("create_by",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPageByCreateBy = selectJoinListPage(page, EquipmentDto.class, wrapperByCreateBy);
        List<EquipmentDto> equipmentDtoListByCreateBy = equipmentDtoPageByCreateBy.getRecords();
        if (!equipmentDtoListByCreateBy.isEmpty()){
            finalResultList.addAll(equipmentDtoListByCreateBy);
        }
//     根据最后修改人名称查询
        MPJLambdaWrapper<Equipment>wrapperByUpdateBy=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("last_update_by",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPageByUpdateBy = selectJoinListPage(page, EquipmentDto.class, wrapperByUpdateBy);
        List<EquipmentDto> equipmentDtoListByUpdateBy = equipmentDtoPageByUpdateBy.getRecords();
        if (!equipmentDtoListByUpdateBy.isEmpty()){
            finalResultList.addAll(equipmentDtoListByUpdateBy);
        }

//        根据品牌查询
        MPJLambdaWrapper<Equipment>wrapperByBrand=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("brand",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPageByBrand = selectJoinListPage(page, EquipmentDto.class, wrapperByBrand);
        List<EquipmentDto> equipmentDtoListByBrand = equipmentDtoPageByBrand.getRecords();
        if (!equipmentDtoListByBrand.isEmpty()){
            finalResultList.addAll(equipmentDtoListByBrand);
        }
//    根据encode查询
        MPJLambdaWrapper<Equipment>wrapperByEncode=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("encode",name.toUpperCase())
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Equipment::getUpdateTime)
//                .selectCollection(EquipmentPhoto.class,EquipmentDto::getEquipmentPhotoList)
//                .leftJoin(EquipmentPhoto.class,EquipmentPhoto::getEquipmentEncode,Equipment::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<EquipmentDto> equipmentDtoPageByEncode = selectJoinListPage(page, EquipmentDto.class, wrapperByEncode);
        List<EquipmentDto> equipmentDtoListByEncode = equipmentDtoPageByEncode.getRecords();
        if (!equipmentDtoListByEncode.isEmpty()){
            finalResultList.addAll(equipmentDtoListByEncode);
        }
        List<EquipmentDto>equipmentDTOs=new ArrayList<>(finalResultList);

        //        对List内部元素重新按照创建时间从晚到早重新排序
        equipmentDTOs.sort(new Comparator<EquipmentDto>() {
            @Override
            public int compare(EquipmentDto o1, EquipmentDto o2) {
                Date createTime1 = o1.getUpdateTime();
                Date createTime2 = o2.getUpdateTime();
                return createTime2.compareTo(createTime1);
            }
        });


        return SaResult.data(equipmentDTOs);
    }

    @Override
    public SaResult getCountByMultifunctionNameService(String name) {
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        if (StrUtil.isBlank(StrUtil.trim(name))){
            return SaResult.error("查询的名称不能为空！");
        }


//       应该用EquipmentDto，而不是Equipment，因为后面返回的是EquipmentDto对象

        Set<Equipment>finalResultList=new HashSet<>();
//        跟一对多一样
        MPJLambdaWrapper<Equipment>wrapperByEquipName=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("eq_name",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress);
        List<Equipment> equipmentListByEquipmentName =list(wrapperByEquipName);
        if (!equipmentListByEquipmentName.isEmpty()){
            finalResultList.addAll(equipmentListByEquipmentName);
        }

//        根据材料类型查询
        MPJLambdaWrapper<Equipment>wrapperByTypeName=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("type_name",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress);
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        List<Equipment> equipmentListByTypeName = list(wrapperByTypeName);
        if (!equipmentListByTypeName.isEmpty()){
            finalResultList.addAll(equipmentListByTypeName);
        }

//        根据创建人名称查询
        MPJLambdaWrapper<Equipment>wrapperByCreateBy=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("create_by",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress);
        List<Equipment> equipmentListByCreateBy = list(wrapperByCreateBy);
        if (!equipmentListByCreateBy.isEmpty()){
            finalResultList.addAll(equipmentListByCreateBy);
        }
//     根据最后修改人名称查询
        MPJLambdaWrapper<Equipment>wrapperByUpdateBy=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("last_update_by",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress);
        List<Equipment> equipmentListByUpdateBy = list(wrapperByUpdateBy);
        if (!equipmentListByUpdateBy.isEmpty()){
            finalResultList.addAll(equipmentListByUpdateBy);
        }

//        根据品牌查询
        MPJLambdaWrapper<Equipment>wrapperByBrand=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("brand",name)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress);
        List<Equipment> equipmentListByBrand = list(wrapperByBrand);
        if (!equipmentListByBrand.isEmpty()){
            finalResultList.addAll(equipmentListByBrand);
        }
//    根据encode查询
        String encodeUpperCase = name.toUpperCase();
        MPJLambdaWrapper<Equipment>wrapperByEncode=new MPJLambdaWrapper<Equipment>()
                .selectAll(Equipment.class)
                .like("encode",encodeUpperCase)
                .eq(!PublicTools.checkLoginRole(),Equipment::getLocation, locationAddress);
        List<Equipment> equipmentListByEncode = list(wrapperByEncode);

        if (!equipmentListByEncode.isEmpty()){
            finalResultList.addAll(equipmentListByEncode);
        }
        return SaResult.data(finalResultList.size());
    }

    @Override
    public SaResult modifyEquipmentStatusService(Equipment equipment) {
        boolean b = updateById(equipment);
        return b?SaResult.ok():SaResult.error();
    }


    public boolean fileOperation(String encode, MultipartFile[] eqPhotoList, HttpServletRequest request) {
//        创建一个equipmentPhotoDto集合作为向数据库写数据的容器
        List<EquipmentPhotoDto> equipmentPhotoDtoList = new ArrayList<>();
//        创建日期目录
        String format = sdf.format(new Date());
//        详细目录名是date,存储equipphoto的目录，日期目录，encode目录
        String realPath = fileLocation + equipPhotoPath + format + encode;
//        创建文件对象
        File folder = new File(realPath);
//        定义全网络路径
        String url;
//        创建目录

        if (!folder.exists()) {
            folder.mkdirs();
        }
//        把前端传进来的文件列表遍历，并写进硬盘中，同时写入数据库中
        for (MultipartFile multipartFile : eqPhotoList) {
            EquipmentPhotoDto equipmentPhotoDto=new EquipmentPhotoDto();
//            获取文件的原始文件名，并取得文件后缀名，如.jpg
            String originalFilename = multipartFile.getOriginalFilename();
            int i = 0;
            if (originalFilename != null) {
                i = originalFilename.lastIndexOf(".");
            }
            String substring;
            String newFileName;
            if (originalFilename != null) {
//             把截取文件名的后缀  “.jpg”
                substring = originalFilename.substring(i).toLowerCase();
//            重新拼接文件名加.jpg，前缀是登录名，如登录名为eric，整照片的全名就是eric.jpg
//            为避免文件名出行由于菜单名称相同，而相同造成覆盖，采用了一个7位的随机字符串拼接
                newFileName = RandomUtil.randomString(4).toUpperCase() +substring;
//            }
                try {
//                    通过transferTo方法，把文件写入磁盘
                    multipartFile.transferTo(new File(folder, newFileName));





//                    拼接全网络文件路径
//                    url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/file" +equipPhotoPath+ format +encode+"/"+ newFileName;
                    url = equipPhotoPath+ format +encode+"/"+ newFileName;






                    //                    把url,encode,equipmentPhotoDto写入equipmentPhotoDto对象相应字段中
                    equipmentPhotoDto.setPhotoUrl(url);
                    equipmentPhotoDto.setEquipmentEncode(encode);
                    equipmentPhotoDtoList.add(equipmentPhotoDto);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
//        把equipmentPhotoDto列表转换为equipmentPhoto列表
        List<EquipmentPhoto> equipmentPhotoList = BeanUtil.copyToList(equipmentPhotoDtoList, EquipmentPhoto.class);
//        写入数据库
        return equipmentPhotoService.saveBatch(equipmentPhotoList);
    }

    EquipmentDto checkEquipmentDto(EquipmentDto equipmentDto){

        if (StrUtil.isBlank(StrUtil.trim(equipmentDto.getBrand()))){
            equipmentDto.setBrand(null);
        }
        else {
            equipmentDto.setBrand(StrUtil.trim(equipmentDto.getBrand()));
        }


        if (StrUtil.isBlank(StrUtil.trim(equipmentDto.getModel()))){
            equipmentDto.setModel(null);
        }
        else {
            equipmentDto.setModel(StrUtil.trim(equipmentDto.getModel()));
        }


        if (StrUtil.isBlank(StrUtil.trim(equipmentDto.getDescription()))){
            equipmentDto.setDescription(null);
        }


        if (StrUtil.isBlank(StrUtil.trim(equipmentDto.getPieces()))){
            equipmentDto.setPieces(null);
        }
        else {
            equipmentDto.setPieces(StrUtil.trim(equipmentDto.getPieces()));
        }


        if (StrUtil.isBlank(StrUtil.trim(equipmentDto.getLocation()))){
            equipmentDto.setLocation(null);
        }
        else {
            equipmentDto.setLocation(StrUtil.trim(equipmentDto.getLocation()));
        }

        if (StrUtil.isBlank(StrUtil.trim(equipmentDto.getEqName()))){
            equipmentDto.setEqName(null);
        }
        else {
            equipmentDto.setEqName(StrUtil.trim(equipmentDto.getEqName()));
        }

        if (equipmentDto.getNumber()==null||equipmentDto.getNumber()<=0){
            equipmentDto.setNumber(null);
        }

        return equipmentDto;

    }

}
